import { nextTick } from 'vue';
import { isNil, reject } from 'ramda';
import { PanelItemController, SysUIActionTag } from '@ibiz-template/runtime';
import { IAppMenuItem, IPanelRawItem, ISysImage } from '@ibiz/model-core';
import { NavTabsState, TabMsg } from './nav-tabs.state';

/**
 * 导航占位控制器
 *
 * @export
 * @class TopNavTabsController
 * @extends {PanelItemController}
 */
export class NavTabsController extends PanelItemController<IPanelRawItem> {
  declare state: NavTabsState;

  /**
   * 默认激活视图
   */
  public defaultActiveView?: {
    viewName?: string;
    caption?: string;
    sysImage?: ISysImage;
  };

  protected createState(): NavTabsState {
    return new NavTabsState(this.parent?.state);
  }

  /**
   * 当前视图的路由层级，非路由模式不存在。
   * @readonly
   */
  get routeDepth(): number | undefined {
    return this.panel.view.modal.routeDepth;
  }

  /**
   * 导航占位控制器
   * @readonly
   * @type {(IParams | undefined)}
   */
  get navPos(): IParams | undefined {
    return this.panel.panelItems.nav_pos_index as IParams;
  }

  /**
   * clac默认激活项
   */
  async clacDefaultActive(): Promise<void> {
    if (this.navPos && this.navPos.appmenu) {
      const allItems: IAppMenuItem[] = this.navPos.appmenu?.getAllItems();
      // 默认激活的菜单项
      const defaultActiveMenuItem = allItems.find(item => {
        return item.openDefault && !item.hidden;
      });
      if (defaultActiveMenuItem) {
        const menuId = defaultActiveMenuItem.appFuncId || '';
        const app = await ibiz.hub.getAppAsync(
          this.navPos.appmenu.context.srfappid,
        );
        const appFunc = app.getAppFunc(menuId);
        // 如果应用功能存在视图
        if (appFunc && appFunc.appViewId) {
          const { codeName, caption, sysImage } = await ibiz.hub.getAppView(
            appFunc.appViewId,
          );
          this.defaultActiveView = {
            viewName: codeName,
            caption,
            sysImage,
          };

          // 默认激活项, 应将标签页放到第一项
          this.state.tabItems.unshift({
            key: 'defaultActive',
            ...this.defaultActiveView,
          });
          this.state.defaultActiveKey = 'defaultActive';
        }
      }
    }
  }

  /**
   * 获取tabItem
   * @param {string} key
   * @return {*}
   */
  findTabItem(key: string): TabMsg | undefined {
    return this.state.tabItems.find(item => item.key === key);
  }

  /**
   * 处理菜单默认激活
   */
  onMenuDefaultActive(): void {
    const allItems: IAppMenuItem[] = this.navPos?.appmenu?.getAllItems();
    // 默认激活的菜单项
    const defaultActiveMenuItem = allItems.find(item => {
      return item.openDefault && !item.hidden;
    });
    if (defaultActiveMenuItem) {
      this.navPos?.appmenu.onClickMenuItem(defaultActiveMenuItem.id);
    }
  }

  /**
   * 处理标签默认激活
   */
  handleDefaultActive(): void {
    // 判断首个标签页是否为默认激活项占位，如果是则判断是否执行过处理菜单默认激活逻辑
    const firstItem = this.state.tabItems[0];
    if (firstItem)
      firstItem.key === 'defaultActive'
        ? this.onMenuDefaultActive()
        : this.onTabClick(firstItem.key);
  }

  /**
   * 点击处理
   * @param {string} key
   */
  onTabClick(key: string): void {
    // 如果存在默认激活视图并且没有计算出激活key时, 走菜单项点击执行默认激活项逻辑
    if (key === 'defaultActive') {
      this.onMenuDefaultActive();
    } else {
      this.navPos?.changeView(key);
    }
  }

  /**
   * 更新视图信息
   * @param {string} key
   * @param {{ caption?: string; dataInfo?: string; sysImage?: ISysImage }} info
   */
  async updateViewInfo(
    key: string,
    info: {
      viewName?: string;
      caption?: string;
      dataInfo?: string;
      sysImage?: ISysImage;
    },
  ): Promise<void> {
    // 第一次执行时计算
    if (!this.state.activeTab) await this.clacDefaultActive();

    const findItem = this.findTabItem(key);
    if (findItem) {
      Object.assign(findItem, reject(isNil, info));
      this.refreshItemUI(key);
    } else if (
      this.defaultActiveView &&
      this.defaultActiveView.viewName === info.viewName
    ) {
      // 默认激活项, 应将标签页放到第一项
      Object.assign(this.state.tabItems[0], { key, ...info });
      this.state.defaultActiveKey = this.state.currentKey;
      this.state.activeTab = this.state.currentKey;
    } else {
      this.state.tabItems.push({ key, ...info });
      this.state.activeTab = this.state.currentKey;
    }
  }

  /**
   * 删除某个key对应的数据
   * 仅处理组件自身维护的数据
   * @param {string} key
   */
  removeCache(key: string): void {
    const findIndex = this.state.tabItems.findIndex(item => item.key === key);
    if (findIndex !== -1) {
      this.state.tabItems.splice(findIndex, 1);
    }
  }

  /**
   * 是否为默认激活项
   */
  isDefaultActiveKey(key: string): boolean {
    return !!(this.state.defaultActiveKey === key);
  }

  /**
   * 删除分页
   * @param {string} key
   */
  async onTabRemove(key: string): Promise<void> {
    const findIndex = this.state.tabItems.findIndex(item => item.key === key);

    await this.navPos?.closeViewByKeys([key]);
    if (findIndex - 1 < 1) {
      this.handleDefaultActive();
    }
  }

  /**
   * 关闭视图
   * @param {string[]} keys
   */
  async closeViewByKeys(keys: string[]): Promise<void> {
    const removeKeys = keys.filter(
      (key: string) => !this.isDefaultActiveKey(key),
    );
    if (removeKeys.length > 0) {
      await this.navPos?.closeViewByKeys(removeKeys);
    }
  }

  /**
   * 删除其他所有的标签页
   */
  removeOther(): void {
    const currentKey = this.state.currentKey;
    const removeKeys: string[] = [];
    this.state.tabItems.forEach(item => {
      if (item.key !== currentKey) {
        removeKeys.push(item.key);
      }
    });
    this.closeViewByKeys(removeKeys);
  }

  /**
   * 删除左侧的标签页
   */
  removeLeft(): void {
    const currentKey = this.state.currentKey;
    const removeKeys: string[] = [];
    const curIndex = this.state.tabItems.findIndex(
      item => item.key === currentKey,
    );
    if (curIndex !== -1) {
      this.state.tabItems.forEach((item: IParams, index: number) => {
        if (index < curIndex) {
          removeKeys.push(item.key);
        }
      });
    }
    this.closeViewByKeys(removeKeys);
  }

  /**
   * 删除右侧的标签页
   */
  removeRight(): void {
    const currentKey = this.state.currentKey;
    const removeKeys: string[] = [];
    const curIndex = this.state.tabItems.findIndex(
      item => item.key === currentKey,
    );
    if (curIndex !== -1) {
      this.state.tabItems.forEach((item: IParams, index: number) => {
        if (index > curIndex) {
          removeKeys.push(item.key);
        }
      });
    }
    this.closeViewByKeys(removeKeys);
  }

  /**
   * 删除所有的标签页
   */
  async removeAll(): Promise<void> {
    await this.closeViewByKeys(
      this.state.tabItems.map((item: IParams) => item.key),
    );
    this.handleDefaultActive();
  }

  /**
   * 刷新项（解决主信息更新之后界面ui未刷新）
   */
  public refreshItemUI(key: string): void {
    const tempItem = {
      key: 'exampleItem',
      caption: '',
    };
    this.state.tabItems.push(tempItem);
    this.state.activeTab = tempItem.key;
    nextTick(() => {
      this.state.tabItems.pop();
      this.state.activeTab = key;
    });
  }

  /**
   * 刷新当前视图
   */
  public refresh(key: string = this.state.currentKey): void {
    const tabItem = this.findTabItem(key);
    const view = ibiz.util.viewStack.getActives().find(x => x.model.codeName?.toLowerCase() === tabItem?.viewName?.toLowerCase());
    view?.callUIAction(SysUIActionTag.REFRESH);
  }

  /**
   * 处理路由变化
   */
  public onRouteChange(args: IParams): void {
    if (args && args.currentKey === '') {
      this.handleDefaultActive();
    }
  }
}
